package com.liuke.question5;

import com.google.common.collect.Maps;

import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

/**
 * @Auther: 刘科
 * @Date: 2021/07/04/19:40
 * @Description:
 */
public class Server {
    private static Map<String, SocketChannel> clientMap = Maps.newHashMap();


    public static void main(String[] args) throws Exception {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        ServerSocket serverSocket = serverSocketChannel.socket();
        serverSocket.bind(new InetSocketAddress(8088));

        Selector selector = Selector.open();//打开选择器
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);


        while (true) {
            int num = selector.select();
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            selectionKeys.forEach(selectionKey -> {
                SocketChannel client;
                try {
                    if (selectionKey.isAcceptable()) {
                        ServerSocketChannel serverSocketChannel1 = (ServerSocketChannel) selectionKey.channel();
                        client = serverSocketChannel1.accept();
                        client.configureBlocking(false);
                        client.register(selector, SelectionKey.OP_READ);
                        clientMap.put(UUID.randomUUID().toString(), client);
                    } else if (selectionKey.isReadable()) {
                        client = (SocketChannel) selectionKey.channel();
                        ByteBuffer readBuffer = ByteBuffer.allocate(1024);
                        int count = client.read(readBuffer);
                        if (count > 0) {
                            readBuffer.flip();
                            Charset charset = Charset.forName("utf-8");
                            String receiveMessage = String.valueOf(charset.decode(readBuffer).array());
                            //收到client发来的网址，进行解析
                            String result = null;
                            System.out.println(client + ": " + receiveMessage);
                            if (!receiveMessage.contains("连接成功")) {
                                //发送get请求
                                String pageData = HttpClient.getResponseContentBySocket(receiveMessage, "GET");
                                result = analysePage(pageData);
                            } else {
                                result = receiveMessage;
                            }

                            String sendKey = null;
                            for (Map.Entry<String, SocketChannel> entry : clientMap.entrySet()) {
                                if (client == entry.getValue()) {
                                    sendKey = entry.getKey();
                                    break;
                                }
                            }
                            for (Map.Entry<String, SocketChannel> entry : clientMap.entrySet()) {
                                SocketChannel socketChannel = entry.getValue();
                                ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
                                writeBuffer.put((sendKey +  "---- 计算结果：" + result).getBytes());
                                writeBuffer.flip();
                                socketChannel.write(writeBuffer);
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
            selectionKeys.clear();
        }
    }

    private static String analysePage(String pageData) {
//        统计总字符数(包括标点符号)、汉字数、
//        英文字符数、标点符号数
        int totalChar = pageData.length();
        //统计汉字字符
        int chineseCharacter = 0;
        //统计英文字符
        int englishCharacter = 0;
        //标点符号
        int punctuation = 0;
        for (int i = 0; i < pageData.length(); i++) {
            char ch = pageData.charAt(i);
            if (WordUtils.isChinesePunctuation(ch)) {
                //标点
                punctuation++;
            } else if (WordUtils.isChineseByScript(ch)) {
                //中文
                chineseCharacter++;
            } else {
                englishCharacter++;
            }
        }
        return "总字符数：" + totalChar + "; 汉字字符数：" + chineseCharacter + "; 英文字符数：" + englishCharacter + "; " +
                "标点字符数：" + punctuation;
    }


}
